<template>
  <div
    :class="cardClasses"
    :style="cardStyles"
    @click="handleClick"
  >
    <!-- 卡片头部 -->
    <div v-if="$slots.header || title || extra" class="base-card__header">
      <div class="base-card__header-left">
        <slot name="header">
          <div v-if="title" class="base-card__title">{{ title }}</div>
          <div v-if="subtitle" class="base-card__subtitle">{{ subtitle }}</div>
        </slot>
      </div>
      <div v-if="$slots.extra || extra" class="base-card__header-right">
        <slot name="extra">
          <span class="base-card__extra">{{ extra }}</span>
        </slot>
      </div>
    </div>

    <!-- 卡片内容 -->
    <div v-if="$slots.default" class="base-card__content">
      <slot />
    </div>

    <!-- 卡片底部 -->
    <div v-if="$slots.footer" class="base-card__footer">
      <slot name="footer" />
    </div>

    <!-- 加载状态 -->
    <van-loading
      v-if="loading"
      class="base-card__loading"
      :size="loadingSize"
      :color="loadingColor"
      :text="loadingText"
      vertical
    />

    <!-- 空状态 -->
    <van-empty
      v-if="empty && !loading"
      class="base-card__empty"
      :image="emptyImage"
      :description="emptyText"
    />
  </div>
</template>

<script>
import { computed, defineComponent } from 'vue'

export default defineComponent({
  name: 'BaseCard',
  props: {
    /**
     * 卡片标题
     */
    title: {
      type: String,
      default: ''
    },
    /**
     * 卡片副标题
     */
    subtitle: {
      type: String,
      default: ''
    },
    /**
     * 卡片右侧内容
     */
    extra: {
      type: String,
      default: ''
    },
    /**
     * 卡片类型
     */
    type: {
      type: String,
      default: 'default',
      validator: (value) => ['default', 'primary', 'success', 'warning', 'danger', 'info'].includes(value)
    },
    /**
     * 卡片尺寸
     */
    size: {
      type: String,
      default: 'normal',
      validator: (value) => ['large', 'normal', 'small', 'mini'].includes(value)
    },
    /**
     * 是否显示边框
     */
    border: {
      type: Boolean,
      default: true
    },
    /**
     * 是否显示阴影
     */
    shadow: {
      type: [Boolean, String],
      default: false,
      validator: (value) => [true, false, 'always', 'hover', 'never'].includes(value)
    },
    /**
     * 是否圆角
     */
    round: {
      type: Boolean,
      default: false
    },
    /**
     * 是否方形
     */
    square: {
      type: Boolean,
      default: false
    },
    /**
     * 是否可点击
     */
    clickable: {
      type: Boolean,
      default: false
    },
    /**
     * 是否禁用
     */
    disabled: {
      type: Boolean,
      default: false
    },
    /**
     * 是否加载中
     */
    loading: {
      type: Boolean,
      default: false
    },
    /**
     * 加载图标大小
     */
    loadingSize: {
      type: [Number, String],
      default: '24px'
    },
    /**
     * 加载图标颜色
     */
    loadingColor: {
      type: String,
      default: '#c8c9cc'
    },
    /**
     * 加载文本
     */
    loadingText: {
      type: String,
      default: '加载中...'
    },
    /**
     * 是否为空状态
     */
    empty: {
      type: Boolean,
      default: false
    },
    /**
     * 空状态图片
     */
    emptyImage: {
      type: String,
      default: 'default'
    },
    /**
     * 空状态文本
     */
    emptyText: {
      type: String,
      default: '暂无数据'
    },
    /**
     * 自定义样式
     */
    customStyle: {
      type: Object,
      default: () => ({})
    },
    /**
     * 自定义类名
     */
    customClass: {
      type: [String, Array, Object],
      default: ''
    },
    /**
     * 背景颜色
     */
    backgroundColor: {
      type: String,
      default: ''
    },
    /**
     * 内边距
     */
    padding: {
      type: [String, Number],
      default: ''
    },
    /**
     * 外边距
     */
    margin: {
      type: [String, Number],
      default: ''
    },
    /**
     * 宽度
     */
    width: {
      type: [String, Number],
      default: ''
    },
    /**
     * 高度
     */
    height: {
      type: [String, Number],
      default: ''
    }
  },
  emits: ['click'],
  setup(props, { emit }) {
    /**
     * 卡片样式类
     */
    const cardClasses = computed(() => {
      const classes = [
        'base-card',
        `base-card--${props.type}`,
        `base-card--${props.size}`
      ]

      if (props.border) {
        classes.push('base-card--border')
      }

      if (props.shadow === true || props.shadow === 'always') {
        classes.push('base-card--shadow-always')
      } else if (props.shadow === 'hover') {
        classes.push('base-card--shadow-hover')
      }

      if (props.round) {
        classes.push('base-card--round')
      }

      if (props.square) {
        classes.push('base-card--square')
      }

      if (props.clickable) {
        classes.push('base-card--clickable')
      }

      if (props.disabled) {
        classes.push('base-card--disabled')
      }

      if (props.loading) {
        classes.push('base-card--loading')
      }

      if (props.empty) {
        classes.push('base-card--empty')
      }

      if (props.customClass) {
        if (typeof props.customClass === 'string') {
          classes.push(props.customClass)
        } else if (Array.isArray(props.customClass)) {
          classes.push(...props.customClass)
        } else if (typeof props.customClass === 'object') {
          Object.keys(props.customClass).forEach(key => {
            if (props.customClass[key]) {
              classes.push(key)
            }
          })
        }
      }

      return classes
    })

    /**
     * 卡片内联样式
     */
    const cardStyles = computed(() => {
      const styles = { ...props.customStyle }

      if (props.backgroundColor) {
        styles.backgroundColor = props.backgroundColor
      }

      if (props.padding) {
        styles.padding = typeof props.padding === 'number' ? `${props.padding}px` : props.padding
      }

      if (props.margin) {
        styles.margin = typeof props.margin === 'number' ? `${props.margin}px` : props.margin
      }

      if (props.width) {
        styles.width = typeof props.width === 'number' ? `${props.width}px` : props.width
      }

      if (props.height) {
        styles.height = typeof props.height === 'number' ? `${props.height}px` : props.height
      }

      return styles
    })

    /**
     * 点击处理
     */
    const handleClick = (event) => {
      if (!props.disabled && !props.loading) {
        emit('click', event)
      }
    }

    return {
      cardClasses,
      cardStyles,
      handleClick
    }
  }
})
</script>

<style lang="scss" scoped>
.base-card {
  position: relative;
  background-color: #fff;
  overflow: hidden;
  transition: all 0.3s ease;

  &__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px;
    border-bottom: 1px solid #ebedf0;

    &-left {
      flex: 1;
      min-width: 0;
    }

    &-right {
      flex-shrink: 0;
      margin-left: 16px;
    }
  }

  &__title {
    font-size: 16px;
    font-weight: 600;
    color: #323233;
    line-height: 24px;
    margin: 0;
  }

  &__subtitle {
    font-size: 14px;
    color: #646566;
    line-height: 20px;
    margin-top: 4px;
  }

  &__extra {
    font-size: 14px;
    color: #969799;
    line-height: 20px;
  }

  &__content {
    padding: 16px;
  }

  &__footer {
    padding: 16px;
    border-top: 1px solid #ebedf0;
  }

  &__loading {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 1;
  }

  &__empty {
    padding: 32px 16px;
  }

  // 类型样式
  &--primary {
    border-color: #1989fa;

    .base-card__title {
      color: #1989fa;
    }
  }

  &--success {
    border-color: #07c160;

    .base-card__title {
      color: #07c160;
    }
  }

  &--warning {
    border-color: #ff976a;

    .base-card__title {
      color: #ff976a;
    }
  }

  &--danger {
    border-color: #ee0a24;

    .base-card__title {
      color: #ee0a24;
    }
  }

  &--info {
    border-color: #1989fa;

    .base-card__title {
      color: #1989fa;
    }
  }

  // 尺寸样式
  &--large {
    .base-card__header,
    .base-card__content,
    .base-card__footer {
      padding: 24px;
    }

    .base-card__title {
      font-size: 18px;
      line-height: 28px;
    }

    .base-card__subtitle {
      font-size: 16px;
      line-height: 24px;
    }
  }

  &--small {
    .base-card__header,
    .base-card__content,
    .base-card__footer {
      padding: 12px;
    }

    .base-card__title {
      font-size: 14px;
      line-height: 20px;
    }

    .base-card__subtitle {
      font-size: 12px;
      line-height: 18px;
    }
  }

  &--mini {
    .base-card__header,
    .base-card__content,
    .base-card__footer {
      padding: 8px;
    }

    .base-card__title {
      font-size: 12px;
      line-height: 18px;
    }

    .base-card__subtitle {
      font-size: 11px;
      line-height: 16px;
    }
  }

  // 边框样式
  &--border {
    border: 1px solid #ebedf0;
  }

  // 阴影样式
  &--shadow-always {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }

  &--shadow-hover {
    &:hover {
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
    }
  }

  // 圆角样式
  &--round {
    border-radius: 8px;
  }

  // 方形样式
  &--square {
    border-radius: 0;
  }

  // 可点击样式
  &--clickable {
    cursor: pointer;

    &:hover {
      background-color: #f7f8fa;
    }

    &:active {
      background-color: #f2f3f5;
    }
  }

  // 禁用样式
  &--disabled {
    opacity: 0.5;
    cursor: not-allowed;

    .base-card__title,
    .base-card__subtitle,
    .base-card__extra {
      color: #c8c9cc;
    }
  }

  // 加载样式
  &--loading {
    .base-card__content {
      opacity: 0.5;
    }
  }

  // 空状态样式
  &--empty {
    .base-card__content {
      display: none;
    }
  }
}
</style>